package com.qifeng.lab.base.controller;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.servlet.http.HttpServletResponse;

import com.qifeng.common.utils.SecurityUtils;
import com.qifeng.lab.base.domain.*;
import com.qifeng.lab.base.service.ILabBaseDeviceFunService;
import com.qifeng.lab.base.service.ILabBaseDeviceLendService;
import com.qifeng.lab.base.service.ILabBaseDeviceTypeService;
import com.qifeng.system.service.ISysDictDataService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.qifeng.common.annotation.Log;
import com.qifeng.common.core.controller.BaseController;
import com.qifeng.common.core.domain.AjaxResult;
import com.qifeng.common.enums.BusinessType;
import com.qifeng.lab.base.service.ILabBaseDeviceService;
import com.qifeng.common.utils.poi.ExcelUtil;
import com.qifeng.common.core.page.TableDataInfo;
import com.qifeng.common.utils.StringUtils;
import com.qifeng.common.constant.UserConstants;
/**
 * 设备管理Controller
 *
 * @author qifeng
 * @date 2022-11-22
 */
@RestController
@RequestMapping("/labBase/device")
public class LabBaseDeviceController extends BaseController
{
    @Autowired
    private ILabBaseDeviceService labBaseDeviceService;
    @Autowired
    private ISysDictDataService sysDictDataService;
    @Autowired
    private ILabBaseDeviceTypeService labBaseDeviceTypeService;
    @Autowired
    private ILabBaseDeviceFunService labBaseDeviceFunService;
    @Autowired
    private ILabBaseDeviceLendService labBaseDeviceLendService;

    /**
     * 查询设备管理列表
     */
    @PreAuthorize("@ss.hasAnyPermi('labBase:device:list,labBase:device:query')")
    @GetMapping("/list")
    public TableDataInfo list(LabBaseDevice labBaseDevice)
    {
        startPage();
        List<LabBaseDevice> list = labBaseDeviceService.selectLabBaseDeviceList(labBaseDevice);
        return getDataTable(list);
    }

    /**
     * 导出设备管理列表
     */
    @PreAuthorize("@ss.hasPermi('labBase:device:export')")
    @Log(title = "设备管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, LabBaseDevice labBaseDevice)
    {
        List<LabBaseDevice> list = labBaseDeviceService.selectLabBaseDeviceList(labBaseDevice);
        ExcelUtil<LabBaseDevice> util = new ExcelUtil<LabBaseDevice>(LabBaseDevice.class);
        util.exportExcel(response, list, "设备管理数据");
    }

    /**
     * 获取设备管理详细信息
     */
    @PreAuthorize("@ss.hasPermi('labBase:device:query')")
    @GetMapping(value = "/{deviceId}")
    public AjaxResult getInfo(@PathVariable("deviceId") Long deviceId)
    {
        return AjaxResult.success(labBaseDeviceService.selectLabBaseDeviceByDeviceId(deviceId));
    }




    /**
     * 新增设备管理
     */
    @PreAuthorize("@ss.hasPermi('labBase:device:add')")
    @Log(title = "设备管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody LabBaseDevice labBaseDevice)
    {
        /* 重复检查 管理编号 */
        if (StringUtils.isNotEmpty(labBaseDevice.getDeviceCode())
                && UserConstants.NOT_UNIQUE.equals(labBaseDeviceService.checkLabBaseDeviceDeviceCode(labBaseDevice)))
        {
            return AjaxResult.error("操作失败，管理编号已存在");
        }

        return toAjax(labBaseDeviceService.insertLabBaseDevice(labBaseDevice));
    }

    /**
     * 修改设备管理
     */
    @PreAuthorize("@ss.hasPermi('labBase:device:edit')")
    @Log(title = "设备管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody LabBaseDevice labBaseDevice)
    {
        /* 重复检查 管理编号 */
        if (StringUtils.isNotEmpty(labBaseDevice.getDeviceCode())
                && UserConstants.NOT_UNIQUE.equals(labBaseDeviceService.checkLabBaseDeviceDeviceCode(labBaseDevice)))
        {
            return AjaxResult.error("操作失败，管理编号已存在");
        }

        return toAjax(labBaseDeviceService.updateLabBaseDevice(labBaseDevice));
    }

    /**
     * 删除设备管理
     */
    @PreAuthorize("@ss.hasPermi('labBase:device:remove')")
    @Log(title = "设备管理", businessType = BusinessType.DELETE)
	@DeleteMapping("/{deviceIds}")
    public AjaxResult remove(@PathVariable Long[] deviceIds)
    {
        //return toAjax(labBaseDeviceService.deleteLabBaseDeviceByDeviceIds(deviceIds));
        return toAjax(labBaseDeviceService.deleteLabBaseDeviceByDeviceId(deviceIds[0]));
    }




    /***************************************************************************************************************/
    /***************************************************************************************************************/
    /**
     * 送检提醒
     */
    @PreAuthorize("@ss.hasPermi('labBase:device:list')")
    @GetMapping("/ReportRemind")
    public TableDataInfo ReportRemind(LabBaseDeviceReportRemind labBaseDeviceReportRemind)
    {
        startPage();
        List<LabBaseDeviceReportRemind> list = labBaseDeviceService.selectLabBaseDeviceReportRemind(labBaseDeviceReportRemind);
        return getDataTable(list);
    }
    /**
     * 导出设备送检提醒列表
     */
    @PreAuthorize("@ss.hasPermi('labBase:device:export')")
    @Log(title = "设备送检提醒列表", businessType = BusinessType.EXPORT)
    @PostMapping("/ReportRemindExport")
    public void ReportRemindExport(HttpServletResponse response, LabBaseDeviceReportRemind labBaseDeviceReportRemind)
    {
        List<LabBaseDeviceReportRemind> list = labBaseDeviceService.selectLabBaseDeviceReportRemind(labBaseDeviceReportRemind);
        ExcelUtil<LabBaseDeviceReportRemind> util = new ExcelUtil<LabBaseDeviceReportRemind>(LabBaseDeviceReportRemind.class);
        util.exportExcel(response, list, "设备送检提醒管理数据");
    }

    /**
     * 仪器设备检定计划表 LabBaseDeviceReportPlan
     */
    @PreAuthorize("@ss.hasPermi('labBase:device:list')")
    @GetMapping("/ReportPlan")
    public TableDataInfo ReportPlan(LabBaseDeviceReportPlan labBaseDeviceReportPlan)
    {
        startPage();
        List<LabBaseDeviceReportPlan> list = labBaseDeviceService.selectLabBaseDeviceReportPlan(labBaseDeviceReportPlan);
        return getDataTable(list);
    }
    /**
     * 导出 仪器设备检定计划表
     */
    @PreAuthorize("@ss.hasPermi('labBase:device:export')")
    @Log(title = "仪器设备检定计划表", businessType = BusinessType.EXPORT)
    @PostMapping("/ReportPlanExport")
    public void ReportPlanExport(HttpServletResponse response, LabBaseDeviceReportPlan labBaseDeviceReportPlan)
    {
        List<LabBaseDeviceReportPlan> list = labBaseDeviceService.selectLabBaseDeviceReportPlan(labBaseDeviceReportPlan);
        ExcelUtil<LabBaseDeviceReportPlan> util = new ExcelUtil<LabBaseDeviceReportPlan>(LabBaseDeviceReportPlan.class);
        util.exportExcel(response, list, "仪器设备检定计划表");
    }

    /**
     * 设备期间核查表 LabBaseDeviceReportAudit
     */
    @PreAuthorize("@ss.hasPermi('labBase:device:list')")
    @GetMapping("/ReportAudit")
    public TableDataInfo ReportAudit(LabBaseDeviceReportAudit labBaseDeviceReportAudit)
    {
        startPage();
        List<LabBaseDeviceReportAudit> list = labBaseDeviceService.selectLabBaseDeviceReportAudit(labBaseDeviceReportAudit);
        return getDataTable(list);
    }
    /**
     * 导出 设备期间核查表
     */
    @PreAuthorize("@ss.hasPermi('labBase:device:export')")
    @Log(title = "设备管理", businessType = BusinessType.EXPORT)
    @PostMapping("/ReportAuditExport")
    public void ReportAuditExport(HttpServletResponse response, LabBaseDeviceReportAudit labBaseDeviceReportAudit)
    {
        List<LabBaseDeviceReportAudit> list = labBaseDeviceService.selectLabBaseDeviceReportAudit(labBaseDeviceReportAudit);
        ExcelUtil<LabBaseDeviceReportAudit> util = new ExcelUtil<LabBaseDeviceReportAudit>(LabBaseDeviceReportAudit.class);
        util.exportExcel(response, list, "设备期间核查表");
    }



    /******************************************************************************************************************/

    /**
     * 即将要检定的设备列表
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:user:logined')")
    @GetMapping("/deviceFuncList")
    public AjaxResult selectDeviceFuncList(){
        LabBaseDeviceFun labBaseDeviceFun =new LabBaseDeviceFun();
        HashMap<String,Object> params = new HashMap<>();
        params.put("queryType","deviceFuncList");
        labBaseDeviceFun.setParams(params);
        List<LabBaseDeviceFun> list = labBaseDeviceFunService.selectLabBaseDeviceFunList(labBaseDeviceFun);
        return AjaxResult.success(list);
    }


    /**
     * 我领用的设备列表
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:user:logined')")
    @GetMapping("/deviceLendList")
    public AjaxResult selectDeviceLendList(){
        LabBaseDeviceLend labBaseDeviceLend =new LabBaseDeviceLend();
        HashMap<String,Object> params = new HashMap<>();
        params.put("queryType","myDeviceLend");
        params.put("queryBorrowType","borrow");
        labBaseDeviceLend.setParams(params);
        labBaseDeviceLend.setPersonId(SecurityUtils.getLoginUser().getUser().getUserId());
        List<LabBaseDeviceLend> list = labBaseDeviceLendService.selectLabBaseDeviceLendList(labBaseDeviceLend);
        return AjaxResult.success(list);
    }

    /**
     * 柱状图
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:user:logined')")
    @GetMapping("/column")
    public AjaxResult selectColumn(){

        LabBaseDevice labBaseDevice = new LabBaseDevice();
        HashMap<String,Object> params = new HashMap<>();
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        params.put("queryType","column");
        List<LabBaseDevice> labBaseDeviceList = labBaseDeviceService.selectLabBaseDeviceList(labBaseDevice);



        Map<Long,Long> totalState
                = labBaseDeviceList.stream().collect(Collectors.groupingBy(LabBaseDevice::getDeviceType, Collectors.counting()));


        int topN = 8;

        // 首先，将Map的entry转换为Stream，然后按照值（计数）进行排序（降序）
        Stream<Map.Entry<Long, Long>> sortedEntries = totalState.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()));

        // 然后，使用limit截取前N个entry
        List<Map.Entry<Long, Long>> topNEntries = sortedEntries.limit(topN).collect(Collectors.toList());

        // 最后，将这些entry转换回Map
        Map<Long, Long> topNCounts = topNEntries.stream()
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

        int i=0;
        String name =  "";
        String value =  "";
        String json ="";
        String deviceTypeName = "";
        for (Map.Entry<Long, Long> entry : topNCounts.entrySet()){
            if(i>0){
                name+=",";
                value+=",";
            }

            deviceTypeName = getDeviceTypeName(entry.getKey());
            name+="\""+deviceTypeName+"\"";
            value+="\""+entry.getValue()+"\"";

            i++;
        }

        json = "{\"name\":["+name+"],\"value\":["+value+"]}";

        return AjaxResult.success(json);
    }


    /**
     * 曲线图
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:user:logined')")
    @GetMapping("/line")
    public AjaxResult selectLine(){

        LabBaseDeviceLend labBaseDeviceLend =new LabBaseDeviceLend();
        HashMap<String,Object> params = new HashMap<>();
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        params.put("queryType","line");
        params.put("beginTime",year+"-1-1");
        params.put("endTime",year+"-12-31");
        labBaseDeviceLend.setParams(params);
        List<LabBaseDeviceLend> labBaseDeviceLendList = labBaseDeviceLendService.selectLabBaseDeviceLendList(labBaseDeviceLend);


        Map<Integer,Long> totalDate
                = labBaseDeviceLendList.stream()
                .filter(item->item.getLendDateMonth()>0)
                .collect(Collectors.groupingBy(LabBaseDeviceLend::getLendDateMonth, Collectors.counting()));

        for (int i = 1; i <= 12; i++) {
            if(!totalDate.containsKey(i)){
                totalDate.put(i,0L);
            }
        }


        int i=0;
        String json = "";
        String name = "";
        String value = "";
        for (Map.Entry<Integer, Long> entry : totalDate.entrySet()){
            if(i>0){
                name+=",";
                value+=",";
            }
            name+="\""+(entry.getKey().intValue())+"月\"";
            value+="\""+entry.getValue()+"\"";

            i++;
        }

        json = "{\"name\":["+name+"],\"value\":["+value+"]}";

        return AjaxResult.success(json);
    }

    /**
     * 饼状图
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:user:logined')")
    @GetMapping("/pie")
    public AjaxResult selectPie(){

        LabBaseDevice labBaseDevice = new LabBaseDevice();
        HashMap<String,Object> params = new HashMap<>();
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        params.put("queryType","pie");
        labBaseDevice.setParams(params);

        List<LabBaseDevice> labBaseDeviceList = labBaseDeviceService.selectLabBaseDeviceList(labBaseDevice);

        Map<Long,Long> totalState
                = labBaseDeviceList.stream().collect(Collectors.groupingBy(LabBaseDevice::getDeviceState, Collectors.counting()));


        int topN = 8;

        // 首先，将Map的entry转换为Stream，然后按照值（计数）进行排序（降序）
        Stream<Map.Entry<Long, Long>> sortedEntries = totalState.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()));

        // 然后，使用limit截取前N个entry
        List<Map.Entry<Long, Long>> topNEntries = sortedEntries.limit(topN).collect(Collectors.toList());

        // 最后，将这些entry转换回Map
        Map<Long, Long> topNCounts = topNEntries.stream()
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

        int i=0;
        String name =  "";
        String json ="";
        for (Map.Entry<Long, Long> entry : topNCounts.entrySet()){
            if(i>0){
                json+=",";
            }
            name = sysDictDataService.selectDictLabel("lab_base_device_state",entry.getKey().toString());

            json+="{ \"value\": \""+entry.getValue()+"\", \"name\": \""+name+"\"}";
            i++;
        }

        json ="["+json+"]";

        return AjaxResult.success(json);
    }

    private  String getDeviceTypeName(Long deviceTypeId){
        String name = "";
        LabBaseDeviceType labBaseDeviceType = labBaseDeviceTypeService.selectLabBaseDeviceTypeByDeviceTypeId(deviceTypeId);
        if(StringUtils.isNotNullEmpty(labBaseDeviceType)){
            name = labBaseDeviceType.getTypeName();
        }
        return name;
    }


}
